//
//  ViewController.m
//  HealthKitDemo
//
//  Created by LZP on 2018/9/3.
//  Copyright © 2018年 鹏鹏. All rights reserved.
//

#import "ViewController.h"

#import <Foundation/Foundation.h>
#import <HealthKit/HealthKit.h>

#import "NSArray+Log.h"
#import "NSDictionary+Log.h"

#import "AppManager.h"

@interface ViewController ()

@property (weak, nonatomic) IBOutlet UIButton *addButton;
@property (weak, nonatomic) IBOutlet UIButton *writeButton;
@property (weak, nonatomic) IBOutlet UIView *logView;
@property (weak, nonatomic) IBOutlet UIButton *resetLastHour;

@property (nonatomic, strong) HKHealthStore *healthStore;

@property (nonatomic, strong) NSMutableArray *stepsData;

@property (nonatomic, strong) NSDate *lastTouch;

@property (nonatomic, assign) BOOL hasAuthorization;

@property (weak, nonatomic) IBOutlet UILabel *lastRecordLabel;
@property (nonatomic, assign) NSInteger lastRecordHour;
@property (nonatomic, strong) NSString *startHour;
@property (weak, nonatomic) IBOutlet UILabel *tipsLabel;

@end

@implementation ViewController

- (HKHealthStore *)healthStore {
    if (Nil == _healthStore) {
        // HKHealthStore —— 关键类（使用HealthKit框架必须创建该类）
        _healthStore = [[HKHealthStore alloc] init];
    }
    return _healthStore;
}

/// 获取读的权限
- (NSSet *)dataTypesToRead {
    // 目前我们只获取步数权限, 可以增加
    HKQuantityType *stepCountType = [HKObjectType quantityTypeForIdentifier:HKQuantityTypeIdentifierStepCount];
    return [NSSet setWithObjects:stepCountType, nil];
}

/// 获取写的权限
- (NSSet *)dataTypesToWrite {
    HKQuantityType *stepCountType = [HKQuantityType quantityTypeForIdentifier:HKQuantityTypeIdentifierStepCount];
    return [NSSet setWithObjects:stepCountType, nil];
}

/// 数据
- (NSMutableArray *)stepsData {
    if (nil == _stepsData) {
        _stepsData = [NSMutableArray array];
    }
    return _stepsData;
}

- (void)setLastRecordHour:(NSInteger)lastRecordHour {
    _lastRecordHour = lastRecordHour % 24;
    [[NSUserDefaults standardUserDefaults] setInteger:_lastRecordHour forKey:@"lastRecordHour"];
    self.startHour = [NSString stringWithFormat:@"%02ld", (long)_lastRecordHour + 1];
    dispatch_async(dispatch_get_main_queue(), ^{
        self.lastRecordLabel.text = [NSString stringWithFormat:@"%02ld", (long)self.lastRecordHour];
    });
}

- (void)viewDidLoad {
    [super viewDidLoad];
    self.lastRecordHour = -1;
    self.lastRecordHour = [[NSUserDefaults standardUserDefaults] integerForKey:@"lastRecordHour"];
    if (self.lastRecordHour > 0) {
    } else {
        self.lastRecordHour = 5;
    }
    [self setUpAllViews];
    [self setUpHealthKit];
}

- (void)setUpAllViews {
    CGFloat width = self.addButton.frame.size.width;
    self.addButton.layer.cornerRadius = width * 0.5;
    self.addButton.layer.masksToBounds = YES;
    
    width = self.writeButton.frame.size.width;
    self.writeButton.layer.cornerRadius = width * 0.5;
    self.writeButton.layer.masksToBounds = YES;
    
    self.resetLastHour.layer.cornerRadius = 5;
    self.resetLastHour.layer.masksToBounds = YES;
}

/// 准备healthKit
- (void)setUpHealthKit {
    self.hasAuthorization = NO;
    // 检查healthKit是否可用
    [self checkHealthKitAvailable];
    
    // 设置healtthKit权限
    [self setAuthorizationOfHealthKitCompleteHandler:^(BOOL result) {
        
    }];
}

/// 检测设备是否支持healthKit
- (void)checkHealthKitAvailable {
    // 查询是否设备是否支持HealthKit框架
    if (![HKHealthStore isHealthDataAvailable]) {
        NSLog(@"该设备不支持HealthKit");
        return;
    }
}

/// 注册需要读写的数据类型，也可以在“健康”APP中重新修改
- (void)setAuthorizationOfHealthKitCompleteHandler:(void(^)(BOOL result))completeHandler {
    [self.healthStore requestAuthorizationToShareTypes:[self dataTypesToWrite] readTypes:[self dataTypesToRead] completion:^(BOOL success, NSError * _Nullable error) {
        if (success) {
            NSLog(@"获取步数权限成功");
            self.hasAuthorization = YES;
        } else {
            NSLog(@"获取步数权限失败");
        }
    }];
}

- (IBAction)queryStepCountData:(UIButton *)sender {
    // 查询采样信息
    HKSampleType *sampleType = [HKQuantityType quantityTypeForIdentifier:HKQuantityTypeIdentifierStepCount];
    
    // NSSortDescriptor来告诉healthStore怎么样将结果排序
    NSSortDescriptor *start = [NSSortDescriptor sortDescriptorWithKey:HKSampleSortIdentifierStartDate ascending:NO];
    NSSortDescriptor *end = [NSSortDescriptor sortDescriptorWithKey:HKSampleSortIdentifierEndDate ascending:NO];
    
    // 由于健康中的数据也是通过时间来获取的，所以这里我们要获取当前时间进行对比
    NSDate *now = [NSDate date];
    NSCalendar *calender = [NSCalendar currentCalendar];
    NSUInteger unitFlags = NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay | NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond;
    NSDateComponents *dateComponent = [calender components:unitFlags fromDate:now];
    int hour = (int)[dateComponent hour];
    int minute = (int)[dateComponent minute];
    int second = (int)[dateComponent second];
    NSDate *nowDay = [NSDate dateWithTimeIntervalSinceNow:  - (hour*3600 + minute * 60 + second) ];
    //时间结果与想象中不同是因为它显示的是0区
    NSLog(@"今天%@",nowDay);
    NSDate *nextDay = [NSDate dateWithTimeIntervalSinceNow:  - (hour*3600 + minute * 60 + second)  + 86400];
    NSLog(@"明天%@",nextDay);
    NSPredicate *predicate = [HKQuery predicateForSamplesWithStartDate:nowDay endDate:nextDay options:(HKQueryOptionNone)];
    
    // 查询的基类是HKQuery，这是一个抽象类，能够实现每一种查询目标，这里我们需要查询的步数是一个HKSample类所以对应的查询类是HKSampleQuery。下面的limit参数传1表示查询最近一条数据，查询多条数据只要设置limit的参数值就可以了
    HKSampleQuery *sampleQuery = [[HKSampleQuery alloc] initWithSampleType:sampleType predicate:predicate limit:0 sortDescriptors:@[start,end] resultsHandler:^(HKSampleQuery * _Nonnull query, NSArray<__kindof HKSample *> * _Nullable results, NSError * _Nullable error) {
        //设置一个int型变量来作为步数统计
        int allStepCount = 0;
        
        NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
        dateFormatter.dateFormat = @"yyyy-MM-dd HH:mm:ss";
        for (int i = 0; i < results.count; i ++) {
            //把结果转换为字符串类型
            HKQuantitySample *result = results[i];
            
            if (result.metadata.count > 0) {
                NSLog(@"%@", result.metadata);
            }
            
            if (result.device) {
                continue;
            }
            
            
            HKQuantity *quantity = result.quantity;
            
            // 获取步数的数值
            NSMutableString *stepCount = (NSMutableString *)quantity;
            NSString *stepStr =[ NSString stringWithFormat:@"%@",stepCount];
            //获取51 count此类字符串前面的数字
            NSString *str = [stepStr componentsSeparatedByString:@" "][0];
            int stepNum = [str intValue];
            
            NSLog(@"%@ ----> %@ 时间段 %d步", [dateFormatter stringFromDate:result.startDate], [dateFormatter stringFromDate:result.endDate], stepNum);
            //把一天中所有时间段中的步数加到一起
            allStepCount = allStepCount + stepNum;
        }
        NSLog(@"今天的总步数＝＝＝＝%d",allStepCount);
    }];
    
    // 开始执行查询
    [self.healthStore executeQuery:sampleQuery];
    // 获取到今天到现在为止的步数
}

- (IBAction)resetLastHourButtonClicked:(UIButton *)sender {
    self.lastRecordHour = 5;
}

- (IBAction)queryCurrentData:(UIBarButtonItem *)sender {
    [self getUnUpdatedData:^(NSString *startTime, NSString *endTime, NSInteger result) {
        
    }];
}

- (void)getUnUpdatedData:(void(^)(NSString *startTime, NSString *endTime, NSInteger result))completeHandler {
    NSDateFormatter *dateFormatter = timeFormatter(@"yyyy-MM-dd");
    NSString *startTime = [NSString stringWithFormat:@"%@ %@:00:00", [dateFormatter stringFromDate:[NSDate date]], self.startHour];
    NSString *endTime = [NSString stringWithFormat:@"%@ %@:59:59", [dateFormatter stringFromDate:[NSDate date]], self.startHour];
    [[AppManager sharedAppManager] queryDataFrom:startTime to:endTime status:NO completeHandler:^(NSArray<SectionRecordModel *> *results) {
        NSInteger count = 0;
        for (SectionRecordModel *model in results) {
            if (model.updated == 0) {
                count += model.count;
            }
        }
        dispatch_async(dispatch_get_main_queue(), ^{
            self.tipsLabel.text = [NSString stringWithFormat:@"%@->%@记录了%ld条未提交", startTime, endTime, count];
            if (completeHandler) {
                completeHandler(startTime, endTime, count);
            }
        });
    }];
}

- (IBAction)deleteCaches:(UIBarButtonItem *)sender {
    [[AppManager sharedAppManager] deleteAllCaches];
    [self getUnUpdatedData:^(NSString *startTime, NSString *endTime, NSInteger result) {
        
    }];
}

#pragma mark 更新记录
- (IBAction)updateStepCountData:(UIButton *)sender {
    
    NSDate *nowDate = [NSDate date];
    if (self.lastTouch) {
        NSTimeInterval sepTime = [nowDate timeIntervalSinceDate:self.lastTouch];
        if (sepTime <= 0.5) {
            // 半秒钟之内, 点击无效
            return;
        }
    }
    self.lastTouch = nowDate;
    
    if (self.hasAuthorization) {
        [self addRercord];
    } else {
        __weak typeof(self) weakSelf = self;
        [self setAuthorizationOfHealthKitCompleteHandler:^(BOOL result) {
            [weakSelf addRercord];
        }];
    }
}

// 记录数据
/// 一旦写入不可补充
- (void)addRercord {
    // 添加数据到数据库
    
    NSDateFormatter *dateFormatter = timeFormatter(@"yyyy-MM-dd");
    NSString *startTime = [NSString stringWithFormat:@"%@ %@:00:00", [dateFormatter stringFromDate:[NSDate date]], self.startHour];
    NSString *endTime = [NSString stringWithFormat:@"%@ %@:59:59", [dateFormatter stringFromDate:[NSDate date]], self.startHour];
    
    dateFormatter = timeFormatter(@"yyyy-MM-dd HH:mm:ss");
    NSDate *startDate = [dateFormatter dateFromString:startTime];
    NSDate *endDate = [dateFormatter dateFromString:endTime];
    NSTimeInterval sep = [endDate timeIntervalSinceDate:startDate];
    NSString *currTime = [dateFormatter stringFromDate:[NSDate dateWithTimeInterval:arc4random_uniform((int)sep) sinceDate:startDate]];
    
    int count = arc4random_uniform(100) + 100;
    [[AppManager sharedAppManager] addSingleRecordWithRecordTime:currTime deviceName:@"iPhone" count:count completeHandler:^(BOOL result) {
        if (result) {
            // 界面上跳一下
            CGRect viewFrame = self.logView.frame;
            CGRect frame = CGRectMake(10, viewFrame.size.height - 25, viewFrame.size.width - 20, 21);
            UILabel *label = [[UILabel alloc] init];
            label.text = [NSString stringWithFormat:@"%@ 添加记录%d步", currTime, count];
            label.frame = frame;
            [self.logView addSubview:label];
            
            frame.origin.y -= 25;
            [UIView animateWithDuration:0.8 animations:^{
                label.frame = frame;
                label.alpha = 0;
            } completion:^(BOOL finished) {
                [label removeFromSuperview];
            }];
        }
    }];
}

#pragma mark 写入数据

- (IBAction)writeDataToHealthSys:(UIButton *)sender {
    NSDate *nowDate = [NSDate date];
    if (self.lastTouch) {
        NSTimeInterval sepTime = [nowDate timeIntervalSinceDate:self.lastTouch];
        if (sepTime <= 0.5) {
            // 半秒钟之内, 点击无效
            return;
        }
    }
    self.lastTouch = nowDate;
    
    [self getUnUpdatedData:^(NSString *startTime, NSString *endTime, NSInteger result) {
        UIAlertController *alert = [UIAlertController alertControllerWithTitle:nil message:[NSString stringWithFormat:@"%@->%@记录了%ld条未提交", startTime, endTime, result] preferredStyle:UIAlertControllerStyleAlert];
        UIAlertAction *actionYes = [UIAlertAction actionWithTitle:@"确认继续" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
            // 查询出过去时间段里面, 没有写过的数据
            // 然后一键更新到手机系统里面去
            __weak typeof(self) weakSelf = self;
            NSString *currTime = currentDateString();
            [[AppManager sharedAppManager] queryAllSectRecordBeforeTime:currTime WithStatus:NO completeHandler:^(NSArray<SectionRecordModel *> *results) {
                for (SectionRecordModel *model in results) {
                    if (model.updated == 0) {
                        [weakSelf writeData:model.count startTime:model.startTime endTime:model.endTime CompleteHandler:^(BOOL result) {
                            if (results) {
                                [[AppManager sharedAppManager] updateSectionRecord:model WithStatus:YES completeHandler:^(BOOL result) {
                                    
                                }];
                            }
                        }];
                    }
                }
                self.lastRecordHour += 1;
                dispatch_async(dispatch_get_main_queue(), ^{
                    [self getUnUpdatedData:^(NSString *startTime, NSString *endTime, NSInteger result) {
                        
                    }];
                });
            }];
        }];
        UIAlertAction *actionNO = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:^(UIAlertAction *action) {
        }];
        [alert addAction:actionYes];
        [alert addAction:actionNO];
        [self presentViewController:alert animated:YES completion:nil];
    }];
}

- (void)writeData:(double)stepCount startTime:(NSString *)startTime endTime:(NSString *)endTime CompleteHandler:(void(^)(BOOL result))completeHandler {
    
    // 从健康应用中获取写的权限
    
    //create sample
    HKQuantityType *stepType = [HKQuantityType quantityTypeForIdentifier:HKQuantityTypeIdentifierStepCount];
    HKQuantity *stepQuantity = [HKQuantity quantityWithUnit:[HKUnit countUnit] doubleValue:stepCount];
    
    //sample date
    NSDateFormatter *dateFormatter = timeFormatter(@"yyyy-MM-dd HH:mm:ss");
    NSDate *startDate = [dateFormatter dateFromString:startTime];
    NSDate *endDate = [dateFormatter dateFromString:endTime];
    
    //create sample
    HKQuantitySample *stepSample = [HKQuantitySample quantitySampleWithType:stepType quantity:stepQuantity startDate:startDate endDate:endDate];
    
    //save objects to health kit
    [self.healthStore saveObject:stepSample withCompletion:^(BOOL success, NSError *error) {
        if (success) {
            NSLog(@"Successfully saved objects to health kit");
        } else {
            NSLog(@"Error: %@ %@", error, [error userInfo]);
        }
        completeHandler(success);
    }];
}

@end
